﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace CodeGenerator.Mvvm.ViewModelGenerator.Serialization
{
    internal class XmlViewModelDeserializer
    {

        private DeserializationResults _results;
        

        private void UnreferencedObject(object sender, UnreferencedObjectEventArgs e)
        {
            _results.Warnings.Add(new DeserializationWarning(string.Format("Unreferenced object found at id {0}", e.UnreferencedId), 0,0));
        }

        private void UnknownNode(object sender, XmlNodeEventArgs e)
        {        
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Unknown node {0} found.\r\n", e.Name);

            _results.Warnings.Add(new DeserializationWarning(sb.ToString(), e.LineNumber, e.LinePosition));
        }

        private void UnknownElement(object sender, XmlElementEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Unexpected {0} found. Expected element(s) {1}.\r\n", e.Element.Name, e.ExpectedElements);

            _results.Warnings.Add(new DeserializationWarning(sb.ToString(), e.LineNumber, e.LinePosition));
        }

        private void UnknownAttribute(object sender, XmlAttributeEventArgs e)
        {

            XmlAttribute attrib = e.Attr;
            string expectedAttribs = e.ExpectedAttributes;

            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Unexpected attribute {0} found. Expected attribute(s) {1}.\r\n", e.Attr.Name, e.ExpectedAttributes);

            _results.Warnings.Add(new DeserializationWarning(sb.ToString(), e.LineNumber, e.LinePosition));
          
        }



        internal DeserializationResults Deserialize(string xmlText)
        {
            try
            {

                _results = new DeserializationResults();
                XmlSerializer xs = new XmlSerializer(typeof(ViewModelGenerationOptions));

                StringReader textReader = new StringReader(xmlText);
               
                xs.UnknownElement += new XmlElementEventHandler(UnknownElement);
                xs.UnknownNode += new XmlNodeEventHandler(UnknownNode);
                xs.UnknownAttribute += new XmlAttributeEventHandler(UnknownAttribute);
                xs.UnreferencedObject += new UnreferencedObjectEventHandler(UnreferencedObject);

                try
                {
                    _results.GenerationOptions = (ViewModelGenerationOptions) xs.Deserialize(textReader);
                }
                catch (Exception ex)
                {
                    _results.DeserializationException = ex;
                }

                return _results;
            }
            catch
            {
                throw;
            }
        }

    }
}
